package com.iwhalecloud.bss.kite.cucc.web.service.bigdata.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneOfferInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdFuncVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IAttachmentService;
import com.iwhalecloud.bss.kite.cucc.common.util.DateFormatUtils;
import com.iwhalecloud.bss.kite.cucc.service.inf.InfServiceBus;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.util.FtpConfig;
import com.iwhalecloud.bss.kite.cucc.service.util.FtpUtils;
import com.iwhalecloud.bss.kite.cucc.web.service.bigdata.vo.OppoProdAttr;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class OppoToSceneUtils {
    private static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(OppoToSceneUtils.class);

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private InfServiceBus infServiceBus;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private IOperateSceneOfferInstService operateSceneOfferInstService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;

    @Autowired
    private IAttachmentService attachmentService;

    @Autowired
    private IOperateSceneFuncProdInstService operateSceneFuncProdInstService;
    public static OppoToSceneUtils getInst() {
        return SpringUtil.getBean(OppoToSceneUtils.class);
    }

    /**
     * 将商机信息放在实例里
     * @param oppoNum
     * @param sceneInstId
     * @return
     */
    public Map<String,Object> putOppoToContext(String oppoNum, String sceneInstId){
        if(KiteStringUtils.isEmpty(oppoNum)){//传变更前端参没有商机编码 从公共属性取
            oppoNum = querySceneInstService.getCommonAttrValue(sceneInstId,"USR0001");
        }
        if(KiteStringUtils.isEmpty(oppoNum)) { return null; }
        Map <String,Object> oppoDetail = new HashMap<>();
        Map map=new HashMap();
        map.put("oppoNum",oppoNum);
        Map<String, Object> oppoMap = infServiceBus.queryOppInfodetail(map);
        Map<String,Object> productData = KiteMapUtils.getMap(oppoMap,"productData");
        List<Map> attachList = (List<Map>) KiteMapUtils.getObject(oppoMap,"attachList");
        List<Map> oppoMebs = (List<Map>) KiteMapUtils.getObject(productData,"members");
        List<Map> prodAttrs = (List<Map>) KiteMapUtils.getObject(productData,"productAttrs");
        if(KiteListUtils.isNotEmpty(oppoMebs)){
            Map<String,Map> oppoMebMap = new HashMap<>();
            oppoMebs.forEach(it->oppoMebMap.put((String) it.get("goodsSku"),it));
            oppoDetail.put("OPPO_MEMBERS",oppoMebMap);
        }
        if(KiteListUtils.isNotEmpty(attachList)){
            Map<String,List> oppoAttaList = new HashMap<>();
            attachList.forEach(it->oppoAttaList.put((String) it.get("goodsSku"),(List) KiteMapUtils.getObject(it,"attachinfo")));
            oppoDetail.put("OPPO_ATTA",oppoAttaList);
        }
        oppoDetail.put("PROD_ATTRS",prodAttrs);
        this.operateSceneInstService.putExtParameter(sceneInstId, "OPPO_DETAIL", oppoDetail);
        return oppoDetail;
    }

    public Map<String,Object> putOppoMembToContext(String cateId, String sceneInstId){
        List<DcPublic> dcPublic = DcPublicCache.getByPkey("20210506001",cateId);
        if(KiteListUtils.isEmpty(dcPublic)) { return null; }
        String oppoNum = querySceneInstService.getCommonAttrValue(sceneInstId,"USR0001");
        if(KiteStringUtils.isEmpty(oppoNum)) { return null; }
        Map <String,Object> oppoDetail = new HashMap<>();
        Map map=new HashMap();
        map.put("oppoNum",oppoNum);
        Map<String, Object> oppoMap = infServiceBus.queryOppInfodetail(map);
        Map<String,Object> productData = KiteMapUtils.getMap(oppoMap,"productData");
        List<Map> oppoMebs = (List<Map>) KiteMapUtils.getObject(productData,"members");
        if(KiteListUtils.isNotEmpty(oppoMebs)){
            Map<String,Map> oppoMebMap = new HashMap<>();
            oppoMebs.forEach(it->oppoMebMap.put((String) it.get("goodsSku"),it));
            oppoDetail.put("OPPO_MEMBERS",oppoMebMap);
        }
        this.operateSceneInstService.putExtParameter(sceneInstId, "OPPO_DETAIL", oppoDetail);
        return oppoDetail;
    }

    /**
     *
     * @param oppoDetail
     * @param sceneInstId
     * @param offerId
     * @param custId
     */
    public void initOppoProdToScene(Map oppoDetail,String sceneInstId,String offerId,String custId,String goodsSpu){
        if(KiteMapUtils.isNotEmpty(oppoDetail)){
            List<OppoProdAttr> prodAttrs =JSONArray.parseArray(JSON.toJSONString(KiteMapUtils.getObject(oppoDetail,"PROD_ATTRS")), OppoProdAttr.class);
            Map<String,Map> oppoMebs = KiteMapUtils.getMap(oppoDetail,"OPPO_MEMBERS");
            Map<String,Map> attachs = (Map<String, Map>) KiteMapUtils.getMap(oppoDetail,"OPPO_ATTA");

            List<KiteOfferInst> kiteOfferInsts = this.querySceneInstService.listMainOfferInsts(sceneInstId,offerId);
            if(KiteListUtils.isNotEmpty(kiteOfferInsts)){
                KiteOfferInst kiteOfferInst = kiteOfferInsts.get(0);
                String saleGoodsCode = kiteOfferInst.getAttrValue("saleGoodsCode");
                String saleGoodsName = kiteOfferInst.getAttrValue("saleGoodsName");
                if(KiteStringUtils.isEmpty(saleGoodsCode)){
                    saleGoodsCode = goodsSpu;
                }
                if(KiteStringUtils.isEmpty(saleGoodsName)){
                    saleGoodsName = OfferCache.get(goodsSpu).getOfferName();
                }
                String offerInstId = kiteOfferInst.getOfferInstId();
                List<KiteProdInst> prodInsts = querySceneInstService.listProdInstsFromOfferInst(custId, offerInstId);
                KiteProdInst prodInst = prodInsts.get(0);
                operateOppoAttrToKiteAttr(prodInst,prodAttrs,sceneInstId);
                if(KiteMapUtils.isNotEmpty(attachs)&&attachs.containsKey(kiteOfferInst.getSpecId())){
                    setOppoAttrs((List<Map>) attachs.get(kiteOfferInst.getSpecId()),sceneInstId,prodInst);
                }
                //附加产品
                if(KiteMapUtils.isNotEmpty(oppoMebs)){
                    for (Map.Entry<String,Map> omEntry:oppoMebs.entrySet()) {
                        String mebGoodSku = omEntry.getKey();
                        List<KiteOfferInst> kiteOfferInstMebs = this.querySceneInstService.listMainOfferInsts(sceneInstId, mebGoodSku);
                        if(KiteListUtils.isEmpty(kiteOfferInstMebs)){
                            KiteOfferInst kiteOfferInstMeb = operateSceneOfferInstService.addOfferInst(sceneInstId, offerInstId, mebGoodSku, null, custId, ContextUtil.getUserId().toString()).getResultObject();
                            CuccPosServiceUtils.setExtParamValue(kiteOfferInstMeb, sceneInstId, "saleGoodsCode", saleGoodsCode);
                            CuccPosServiceUtils.setExtParamValue(kiteOfferInstMeb, sceneInstId, "saleGoodsName", saleGoodsName);
                            this.operateSceneInstService.addInst(sceneInstId, kiteOfferInstMeb);
                            List<KiteProdInst> mebProdInsts = querySceneInstService.listProdInstsFromOfferInst(custId, kiteOfferInstMeb.getOfferInstId());
                            if(KiteListUtils.isNotEmpty(mebProdInsts)){
                                KiteProdInst prodInstMeb = mebProdInsts.get(0);
                                if(KiteMapUtils.isNotEmpty(attachs)&&attachs.containsKey(mebGoodSku)){
                                   setOppoAttrs((List<Map>) attachs.get(mebGoodSku),sceneInstId,prodInstMeb);
                                }
                                List<OppoProdAttr> oppoMebAttrs =JSONArray.parseArray(JSON.toJSONString(KiteMapUtils.getObject(omEntry.getValue(),"serviceAttrs")), OppoProdAttr.class);
                                List<KiteAttr> connectButtonTypeAttrs = prodInstMeb.listAttrs().stream().filter(attr -> KiteStringUtils.equals(KeyConsts.GEN_LOGIC, attr.getAttrValueTypeId())).collect(Collectors.toList());
                                Map<String,List<OppoProdAttr>> grpMap = this.groupAttr(oppoMebAttrs);
                                if(KiteListUtils.isNotEmpty(connectButtonTypeAttrs)){
                                    for (KiteAttr kiteAttr : connectButtonTypeAttrs){
                                        Product product = ProductCache.get(kiteAttr.getGroupId());
                                        if(Objects.nonNull(product)&&grpMap.containsKey(product.getProdNbr())&&KiteStringUtils.equals(product.getProdFuncType(), KeyConsts.PROD_FUNC_TYPE_102)){
                                            //若营销中心传多组格式 从json中取值还原 若营销中心平铺传值销售支持多组 则根据groupid为一组的还原
                                            List<OppoProdAttr> oppoProdAttrs = grpMap.get(product.getProdNbr());
                                            if(oppoProdAttrs.size()==1&&oppoProdAttrs.get(0).getAttrValue().startsWith("{")){
                                                JSONObject jsonAttrs = JSONObject.parseObject(oppoProdAttrs.get(0).getAttrValue());
                                                Set<String> groupKeys = jsonAttrs.keySet();
                                                for(String groupKey:groupKeys){
                                                    String attrStrs = jsonAttrs.getString(groupKey);
                                                    if(KiteStringUtils.isNotEmpty(attrStrs)){
                                                        this.addFuncProd(sceneInstId,prodInstMeb,product,JSON.parseArray(attrStrs,OppoProdAttr.class),custId,ContextUtil.getSimpleLoginInfo().getStaffId().toString());
                                                    }
                                                }
                                            }else {
                                                this.addFuncProd(sceneInstId,prodInstMeb,product,oppoProdAttrs,custId,ContextUtil.getSimpleLoginInfo().getStaffId().toString());
                                            }
                                            grpMap.remove(product.getProdNbr());
                                        }
                                    }
                                }
                                if(KiteMapUtils.isNotEmpty(grpMap)){
                                    Iterator<Map.Entry<String, List<OppoProdAttr>>> iterator = grpMap.entrySet().iterator();
                                    while (iterator.hasNext()){
                                        Map.Entry<String, List<OppoProdAttr>> next = iterator.next();
                                        List<OppoProdAttr> oppoProdAttrs = next.getValue();
                                        operateOppoAttrToKiteAttr(prodInstMeb,oppoProdAttrs,sceneInstId);
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }
    }
    private void addFuncProd(String sceneInstId,KiteProdInst prodInst,Product product,List<OppoProdAttr> oppoProdAttrs,String custId,String staffId){
        String prodInstId = prodInst.getProdInstId();
        DataResult<ProdFuncVO> result = operateSceneFuncProdInstService.addFuncProdInst(sceneInstId, prodInstId, product.getProdId(), custId, staffId);
        KiteProdInstFunc prodInstFunc = this.querySceneInstService.getProdInstFunc(custId, result.getResultObject().getProdInstId());
        oppoProdAttrs.forEach(oppoProdAttr -> {
            String valueDesc = oppoProdAttr.getAttrValueDesc();
            String value = oppoProdAttr.getAttrValue();
            if(KiteStringUtils.isEmpty(value)){
                value = valueDesc;
            }
            String code = oppoProdAttr.getAttrCode();
            operateSceneFuncProdInstService.updateFuncProdInstAttr(KiteWebContext.getContext().getCurrentSceneInstId(), prodInstId, prodInstFunc.getProdInstId(),
                code, value, valueDesc, KiteWebContext.getContext().getCustId(),
                staffId, null);
        });
    }
    private Map<String,List<OppoProdAttr>> groupAttr(List<OppoProdAttr> oppoProdAttrs){
        Map<String,List<OppoProdAttr>> resMap = new HashMap<>();
        if(KiteListUtils.isNotEmpty(oppoProdAttrs)){
            for(OppoProdAttr oppoProdAttr:oppoProdAttrs){
                String groupId = oppoProdAttr.getGroupId();
                List<OppoProdAttr> oppoProdAttrList = resMap.get(groupId);
                if(KiteListUtils.isEmpty(oppoProdAttrList)){
                    oppoProdAttrList = new ArrayList<>();
                    resMap.put(groupId,oppoProdAttrList);
                }
                oppoProdAttrList.add(oppoProdAttr);
            }
        }
        return  resMap;
    }
    private void operateOppoAttrToKiteAttr(KiteProdInst prodInst,List<OppoProdAttr>  oppoAttrs,String sceneInstId){
        if(KiteListUtils.isEmpty(oppoAttrs)) { return; }
        Map<String,List<OppoProdAttr>> grpAttrs = new HashMap<>();
        oppoAttrs.forEach(oppoAttr->{
            //String groupId = oppoAttr.getGroupId();
            String valueDesc = oppoAttr.getAttrValueDesc();
            String value = oppoAttr.getAttrValue();
            if(KiteStringUtils.isEmpty(value)&&KiteStringUtils.isNotEmpty(valueDesc)){//code为空时取name
                value = valueDesc;
                if(valueDesc.contains("[")){
                    value = JSON.parseArray(valueDesc).stream().map(j->j.toString()).collect(Collectors.joining(","));
                    valueDesc = value;
                }
            }
            String fldName = oppoAttr.getAttrCode();
            if(prodInst.getAttr(fldName)!=null){
                prodInst.getAttr(fldName).setValue(value);
                prodInst.getAttr(fldName).setValueDesc(valueDesc);
                operateInstAttrService.setAttrValue(prodInst, fldName, value, sceneInstId, null);
            } else {
                System.out.println("fldname--------"+fldName);
            }
        });
    }
    private void setOppoAttrs(List<Map> attaList,String sceneInstId,KiteProdInst prodInst ){
        attaList.forEach(ataIt->{
            String fileName = KiteMapUtils.getString(ataIt,"attachName");
            String fileType = "";
            String fileName_attr = "";
            if(fileName.contains(".")){
                fileType = KiteStringUtils.substring(fileName, fileName.lastIndexOf('.') + 1);
                fileName_attr = KiteStringUtils.substring(fileName, 0,fileName.lastIndexOf('.'));
            }
            String attachLocation = KiteMapUtils.getString(ataIt, "attachLocation");
            //获取sftp相关配置信息
            DcPublic cfg = DcPublicCache.get("202104260949", "ftpAttr");
            if (Objects.isNull(cfg)) {
                ErrorConsts.BUSI_COMMON_ERROR.throwOut("SFTP配置为空或缓存为空！");
            }
            FtpUtils ftpUtil = new FtpUtils();
            try {
                    String ftpHost = cfg.getCodea();
                    String ftpPort = cfg.getCodeb();
                    String ftpUsername = cfg.getCodec();
                    String ftpPassword = cfg.getCoded();
                    String ftpFilePath = cfg.getCodee();
                    //连接sftp
                    FtpConfig confDown = new FtpConfig();
                    confDown.setAddr(ftpHost);
                    confDown.setPort(ftpPort);
                    confDown.setUsername(ftpUsername);
                    confDown.setPassword(ftpPassword);
                    ftpUtil.sftpConnection(confDown);
                    //将sftp上的文件转为byte类型
                    byte[] bytes = ftpUtil.getSftpBytes(ftpFilePath+attachLocation);
/*                  File f = new File("C:\\Users\\xiaowang\\Desktop\\cfg\\1.png");
                    InputStream input = new FileInputStream(f);
                    byte[] bytes = new byte[1000];
                    input.read(bytes);*/
                if (bytes != null && bytes.length>0) {
                        String fldName = KiteMapUtils.getString(ataIt,"attrCode");
                        String fileId = attachmentService.orderCenterFileUpload(fileName, bytes, fileType);
                        String attaVal = prodInst.getAttr(fldName).getValue();
                        JSONArray jsonArray = new JSONArray();
                        if(KiteStringUtils.isNotEmpty(attaVal)){//多个附件的情况
                            jsonArray = JSON.parseArray(attaVal);
                        }
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("fileName",fileName_attr);
                        jsonObject.put("type",fileType);
                        jsonObject.put("attachmentUrl",fileId);
                        jsonObject.put("fileType","99");
                        jsonObject.put("fileTypeName","其他");
                        jsonObject.put("createDate",DateFormatUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                        jsonObject.put("actionType","A");
                        jsonArray.add(jsonObject);
                        String kiteAttrValue = jsonArray.toJSONString();
                        prodInst.getAttr(fldName).setValue(kiteAttrValue);
                        prodInst.getAttr(fldName).setValueDesc(kiteAttrValue);
                        operateInstAttrService.setAttrValue(prodInst, fldName, kiteAttrValue, sceneInstId, null);
                    }
                } catch (Exception e) {
                    LOGGER.error(e);// e.printStackTrace();
                    BssException.throwOut(KeyConsts.LOG_MODULE, "","商机文件获取失败");
            }finally {
                if (ftpUtil != null) {
                    ftpUtil.sftpClose();
                    ftpUtil.sessionClose();
                }
            }
        });
    }
}
